package tests;

import java.util.ArrayList;
import java.util.List;

import jeconbond.automata.INode;
import jeconbond.automata.IOutcome;
import jeconbond.automata.Node;
import jeconbond.automata.Outcome;
import jeconbond.automata.behaviour.ListPlanWalker;
import jeconbond.economic.natural.strategy.NaturalMerchant;
import jeconbond.economic.resources.ResourceType;
import jeconbond.economic.resources.IResourceType;
import jeconbond.economic.resources.ResourceBasket;
import jeconbond.economic.resources.ResourceStorrage;
import jeconbond.economic.resources.ResourceUtils;
import jeconbond.economic.systems.IResourceRedestributionSystem;
import jeconbond.economic.systems.market.IMarketResourceRedestributionSystem;
import jeconbond.economic.systems.market.ISellProposition;
import jeconbond.economic.systems.market.DefaultMarketResourceRedestributionSystem;
import jeconbond.economic.systems.market.SellProposition;
import jeconbond.economic.systems.natural.NaturalResourceRedestributionSystem;
import junit.framework.Assert;
import junit.framework.TestCase;

public class TestGoodsSupport extends TestCase {
	public void testResource() {
		IResourceType rt = new ResourceType("Wood");
		Assert.assertEquals("Wood", rt.getName());
	}
	
	public void testResourceBasket() {
		IResourceType rt = new ResourceType("Wood"); 
		ResourceBasket rb = new ResourceBasket(
				rt,
				10.0
				);
		Assert.assertEquals(rt, rb.type);
		Assert.assertEquals(10.0, rb.value);
	}
	
	public void testNaturalResourceRedistribution() {
		NaturalResourceRedestributionSystem nrrs = new NaturalResourceRedestributionSystem(); 
		IResourceRedestributionSystem rrs = nrrs;
		Assert.assertNotNull(rrs);
		IResourceType rt = new ResourceType("Wood");
		Assert.assertEquals(0.0, nrrs.howMuchWasStored(rt));
		ResourceBasket rb = new ResourceBasket(
				rt,
				10.0
				);
		nrrs.storeResource(rb.type, rb.value);
		Assert.assertEquals(10.0, nrrs.howMuchWasStored(rt));
		Assert.assertEquals(3.0, nrrs.receiveResource(rt, 3.0));
		Assert.assertEquals(7.0, nrrs.howMuchWasStored(rt));
		Assert.assertEquals(7.0, nrrs.receiveResource(rt, 10.0));
	}
	
	public void testMarketResourceRedistribution() {
		IMarketResourceRedestributionSystem mrrs = new DefaultMarketResourceRedestributionSystem(); 
		IResourceRedestributionSystem rrs = mrrs;
		Assert.assertNotNull(rrs);
		IResourceType rt = new ResourceType("Wood");
		ISellProposition[] propList = mrrs.getSellPropositionsList(rt);
		Assert.assertEquals(0, propList.length);
		ResourceStorrage rs = new ResourceStorrage();
		rs.storeResource(rt, 3.0);
		mrrs.registerProposition(new SellProposition(rt, 1.0, rs, null));
		propList = mrrs.getSellPropositionsList(rt);
		Assert.assertEquals(1.0, propList[0].getPrice());
		Assert.assertEquals(3.0, propList[0].getSellerStorrage().howMuchWasStored(rt));
	}
	
	public void testNaturalMerchantPurchaseIFFenoughtAndNecessary() {
		NaturalResourceRedestributionSystem nrrs = new NaturalResourceRedestributionSystem();
		ResourceStorrage irs = new ResourceStorrage();
		ResourceStorrage ors = new ResourceStorrage();
		List<IOutcome> plan = new ArrayList<IOutcome>();
		INode n1 = new Node("n1");
		IResourceType wood = new ResourceType("Wood");
		plan.add(new Outcome(n1, new ResourceBasket(wood, 1.0)));
		ListPlanWalker walker = new ListPlanWalker(plan, irs, ors);
		NaturalMerchant merchant = new NaturalMerchant(
				irs, 
				ors,
				walker,
				nrrs
		);
		nrrs.storeResource(wood, 0.5);
		merchant.processPurchase();
		Assert.assertEquals(0.5, nrrs.howMuchWasStored(wood));
		irs.storeResource(wood, 0.7);
		merchant.processPurchase();
		Assert.assertEquals(0.7 - 0.5, nrrs.howMuchWasStored(wood));
	}
	
	public void testPossibleWalk() {
		ResourceStorrage inputRS = new ResourceStorrage();
		IResourceType[] r = ResourceUtils.generateResources("r", 2);
		inputRS.storeResource(new ResourceBasket(r[0], 1.5));
		inputRS.storeResource(new ResourceBasket(r[1], 1.1));
		IOutcome out = new Outcome(
				null, 
				new ResourceBasket(r[0], 1.0),
				new ResourceBasket(r[1], 1.0),
				new ResourceBasket(r[0], 1.0)
		);
		Assert.assertFalse(ResourceUtils.checkIfResourcesEnought(inputRS, out));
		inputRS.storeResource(new ResourceBasket(r[0], 0.5));
		Assert.assertTrue(ResourceUtils.checkIfResourcesEnought(inputRS, out));
	}
}
